#Boa:Frame:fClient

import wx
import sys, os
import threading
import subprocess
import time,platform

if platform.system()[0]!="W":
    Win=False
    #import fcntl
else:
    Win=True
    
class tryget(threading.Thread):
    def __init__(self, caller):
        threading.Thread.__init__(self)
        self.caller = caller
        self.si=""
        self.t=1
        self.flag=False
        
    def run(self):
        while not self.flag:
            try:
                if self.t==1:
                    delta=self.caller.p.stdout.read(1)
                else:
                    delta=self.caller.p.stderr.read(1)
                self.si+=delta
                if delta=='':
                    self.flag=True
                else:
                    self.caller.upmsg(self.t,delta)
            except:
                self.flag=True
                break

class TETunnel(threading.Thread):
    def __init__(self, caller):
        threading.Thread.__init__(self)
        self.caller = caller
        
    def run(self):
            #try:
            port=self.caller.tcPort.GetValue()
            shost=self.caller.tcSHost.GetValue()
            sport=self.caller.tcSPort.GetValue()
            key=self.caller.tcKey.GetValue()
            bhost=self.caller.tcBHost.GetValue()
            bw=self.caller.tcBw.GetValue()
            arg=["encryptedtunnel","-c","-l",port,"-i",shost,"-p",sport,"-w",bw,"-k",key]
            if bhost!="":
                arg+=["-b",bhost]
            if Win:
                startupinfo = subprocess.STARTUPINFO()
                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                startupinfo.wShowWindow = subprocess.SW_HIDE
                self.p = subprocess.Popen(args=arg,bufsize=0,stdout=subprocess.PIPE,stderr=subprocess.PIPE,startupinfo=startupinfo)
            else:
                self.p = subprocess.Popen(args=arg,bufsize=0,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
            self.t = tryget(self) 
            self.t.setDaemon(True)
            self.t.start()
            self.t2 = tryget(self)
            self.t2.t=0
            self.t2.setDaemon(True)
            self.t2.start()
            self.p.wait()
            wx.CallAfter(self.caller.OnETStopped)

    def upmsg(self, t, text):
            if text=='\r':
                return
            if t==1:
                wx.CallAfter(self.caller.UpdateETDebug,text)
            else:
                wx.CallAfter(self.caller.UpdateETErr,text)

def create(parent):
    return fClient(parent)

[wxID_FCLIENT, wxID_FCLIENTBSUBMIT, wxID_FCLIENTBUTTON1, wxID_FCLIENTSBAS, 
 wxID_FCLIENTSBDEBUG, wxID_FCLIENTSTATICTEXT1, wxID_FCLIENTSTBHOST, 
 wxID_FCLIENTSTBW, wxID_FCLIENTSTKEY, wxID_FCLIENTSTPORT, wxID_FCLIENTSTSHOST, 
 wxID_FCLIENTTCBHOST, wxID_FCLIENTTCBW, wxID_FCLIENTTCDEBUG, 
 wxID_FCLIENTTCERR, wxID_FCLIENTTCKEY, wxID_FCLIENTTCPORT, 
 wxID_FCLIENTTCSHOST, wxID_FCLIENTTCSPORT, 
] = [wx.NewId() for _init_ctrls in range(19)]

class fClient(wx.Frame):
    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wx.Frame.__init__(self, id=wxID_FCLIENT, name=u'fClient', parent=prnt,
              pos=wx.Point(371, 179), size=wx.Size(592, 442),
              style=wx.DEFAULT_FRAME_STYLE, title=u'Client')
        self.SetClientSize(wx.Size(214, 290))

        self.stPort = wx.StaticText(id=wxID_FCLIENTSTPORT, label=u'Port:',
              name=u'stPort', parent=self, pos=wx.Point(16, 16),
              size=wx.Size(30, 17), style=0)

        self.tcPort = wx.TextCtrl(id=wxID_FCLIENTTCPORT, name=u'tcPort',
              parent=self, pos=wx.Point(96, 16), size=wx.Size(104, 27), style=0,
              value=u'')

        self.stSHost = wx.StaticText(id=wxID_FCLIENTSTSHOST,
              label=u'Server Host:', name=u'stSHost', parent=self,
              pos=wx.Point(16, 48), size=wx.Size(72, 17), style=0)

        self.tcSHost = wx.TextCtrl(id=wxID_FCLIENTTCSHOST, name=u'tcSHost',
              parent=self, pos=wx.Point(96, 48), size=wx.Size(104, 27), style=0,
              value=u'')

        self.staticText1 = wx.StaticText(id=wxID_FCLIENTSTATICTEXT1,
              label=u'Server Port:', name='staticText1', parent=self,
              pos=wx.Point(16, 80), size=wx.Size(70, 17), style=0)

        self.tcSPort = wx.TextCtrl(id=wxID_FCLIENTTCSPORT, name=u'tcSPort',
              parent=self, pos=wx.Point(96, 80), size=wx.Size(104, 27), style=0,
              value=u'')

        self.stKey = wx.StaticText(id=wxID_FCLIENTSTKEY, label=u'Secret Key:',
              name=u'stKey', parent=self, pos=wx.Point(16, 112),
              size=wx.Size(66, 17), style=0)

        self.tcKey = wx.TextCtrl(id=wxID_FCLIENTTCKEY, name=u'tcKey',
              parent=self, pos=wx.Point(96, 112), size=wx.Size(104, 128),
              style=wx.TE_MULTILINE, value=u'')

        self.bSubmit = wx.Button(id=wxID_FCLIENTBSUBMIT, label=u'Launch',
              name=u'bSubmit', parent=self, pos=wx.Point(16, 256),
              size=wx.Size(88, 29), style=0)
        self.bSubmit.Bind(wx.EVT_BUTTON, self.OnSubmit, id=wxID_FCLIENTBSUBMIT)

        self.button1 = wx.Button(id=wxID_FCLIENTBUTTON1, label=u'Advance >>>',
              name=u'button1', parent=self, pos=wx.Point(112, 256),
              size=wx.Size(88, 29), style=0)
        self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,
              id=wxID_FCLIENTBUTTON1)

        self.sbAS = wx.StaticBox(id=wxID_FCLIENTSBAS,
              label=u'Advanced Settings', name=u'sbAS', parent=self,
              pos=wx.Point(8, 304), size=wx.Size(200, 120), style=0)

        self.stBHost = wx.StaticText(id=wxID_FCLIENTSTBHOST,
              label=u'Bind Host:', name=u'stBHost', parent=self,
              pos=wx.Point(16, 328), size=wx.Size(62, 17), style=0)

        self.tcBHost = wx.TextCtrl(id=wxID_FCLIENTTCBHOST, name=u'tcBHost',
              parent=self, pos=wx.Point(96, 328), size=wx.Size(96, 27), style=0,
              value=u'127.0.0.1')

        self.stBw = wx.StaticText(id=wxID_FCLIENTSTBW, label=u'Bandwidth:',
              name=u'stBw', parent=self, pos=wx.Point(16, 369), size=wx.Size(69,
              17), style=0)

        self.tcBw = wx.TextCtrl(id=wxID_FCLIENTTCBW, name=u'tcBw', parent=self,
              pos=wx.Point(96, 368), size=wx.Size(96, 24), style=0,
              value=u'102400')

        self.sbDebug = wx.StaticBox(id=wxID_FCLIENTSBDEBUG,
              label=u'Debugging Infomation', name=u'sbDebug', parent=self,
              pos=wx.Point(224, 16), size=wx.Size(344, 408), style=0)

        self.tcDebug = wx.TextCtrl(id=wxID_FCLIENTTCDEBUG, name=u'tcDebug',
              parent=self, pos=wx.Point(240, 48), size=wx.Size(312, 200),
              style=wx.TE_MULTILINE, value=u'')

        self.tcErr = wx.TextCtrl(id=wxID_FCLIENTTCERR, name=u'tcErr',
              parent=self, pos=wx.Point(240, 264), size=wx.Size(312, 144),
              style=wx.TE_MULTILINE, value=u'')

    def __init__(self, parent):
        self._init_ctrls(parent)
        
    def OnButton1Button(self, event):
        if self.button1.GetLabel()[0]=="A":
            self.SetClientSize(wx.Size(590, 430))
            self.button1.SetLabel("<<< Simple")
        else:
            self.SetClientSize(wx.Size(214, 290))
            self.button1.SetLabel("Advanced >>>")
        
    def OnSubmit(self, event):
        if self.bSubmit.GetLabel()[0]=="L":
            self.tcDebug.Clear()
            self.tcErr.Clear()
            self.t = TETunnel(self)
            self.t.setDaemon(True)
            self.t.start()
            self.bSubmit.SetLabel("Stop")
        else:
            self.OnETStopping()
            self.t.p.kill()
    
    def OnETStopping(self):
        pass
    
    def OnETStopped(self):
        self.bSubmit.SetLabel("Launch")
    
    def UpdateETDebug(self, text):
        if not self.isset('self.po'):
            self.po=""
        try:
            self.tcDebug.AppendText(self.po+text)
            self.po=""
        except:
            self.po+=text
    
    def UpdateETErr(self, text):
        if not self.isset('self.po2'):
            self.po2=""
        try:
            self.tcErr.AppendText(self.po2+text)
            self.po2=""
        except:
            self.po2+=text
            
    def isset(self, v):  
        try:  
            type (eval(v))  
        except:  
            return 0  
        else:  
            return 1

class BoaApp1(wx.App):
    def OnInit(self):
        self.main = create(None)
        self.main.Show()
        self.SetTopWindow(self.main)
        return True

def main():
    application = BoaApp1(0)
    application.MainLoop()

if __name__ == '__main__':
    main()
